package com.skyline.spot.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.imagine.core.ResultState;
import net.imagine.core.engine.ImageEngine;
import net.imagine.provider.skyline.ImageResizeResult;
import net.imagine.provider.skyline.LocalImageResizeTask;
import net.imagine.provider.skyline.MultipartImageResizeTask;
import net.imagine.provider.skyline.SkylineImageResizeTask;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.skyline.base.controller.BaseController;
import com.skyline.base.exception.NotLoginException;
import com.skyline.base.type.Activity;
import com.skyline.base.type.Authority;
import com.skyline.common.bean.Page;
import com.skyline.common.util.Constant;
import com.skyline.common.util.ViewPaths;
import com.skyline.common.util.WebHelper;
import com.skyline.spot.model.Spot;
import com.skyline.spot.model.SpotCharacteristic;
import com.skyline.spot.service.SpotCharacteristicService;
import com.skyline.spot.service.SpotService;
import com.skyline.user.model.User;
import com.skyline.wo.model.Album;
import com.skyline.wo.model.Photo;
import com.skyline.wo.service.AlbumService;

@RequestMapping("/spot/chara")
@Controller
public class SpotCharacteristicController extends BaseController {
	private static final Log LOGGER = LogFactory.getLog(SpotCharacteristicController.class);
	private static final String ALBUM_URL_PREFIX = "/album";
	@Autowired
	private SpotCharacteristicService spotCharaService;
	@Autowired
	private SpotService spotService;
	@Autowired
	private AlbumService albumService;

	@Autowired
	private ImageEngine imagine;
	private @Value("${imagine.localStorePath}")
	String localStorePath;
	private @Value("${imagine.baseSize1},${imagine.baseSize2}")
	int[] baseSizes;

	private @Value("${album.uploadphoto.filesize}")
	long maxSizePerFile;

//	private @Value("${view.spotchara.list}")
//	String SCListView;
//	private @Value("${view.spotchara.detail}")
//	String SCView;
//	private @Value("${view.spot.notfound}")
//	String notFoundView;
//	private @Value("${view.spotchara.add}")
//	String addSCView;
//	private @Value("${view.spotchara.uploadphoto}")
//	String upLoadPhotoView;
//	private @Value("${view.user.login}")
//	String loginView;
//	/** /spot/setcharacover */
//	private @Value("${view.spotchara.uploadok}")
//	String uploadOkView;

	@RequestMapping(value = "/{spotId}/list", method = RequestMethod.GET)
	public ModelAndView viewCharListRequest(@PathVariable("spotId") Long spotId, Page page) {
		ModelAndView mav = new ModelAndView();
		page.setSize(2);
		List<SpotCharacteristic> scList = spotCharaService.queryCharacteristicBySpotId(spotId,
				page, Activity.NORMAL);
		mav.setViewName(ViewPaths.SPOTCHARA_LIST);
		mav.addObject("scList", scList);
		return mav;

	}

	@RequestMapping(value = "{spotId}/{scId}", method = RequestMethod.GET)
	public ModelAndView viewCharRequest(@PathVariable("scId") Long scId) {
		ModelAndView mav = new ModelAndView();
		SpotCharacteristic sc = spotCharaService.queryCharacteristicById(scId, Activity.NORMAL);
		if (sc == null) {
			mav.setViewName(ViewPaths.SPOT_NOTFOUND);
		}
		mav.setViewName(ViewPaths.SPOTCHARA_DETAIL);
		mav.addObject("scInfo", sc);
		return mav;

	}

	@RequestMapping(value = "{spotId}/add", method = RequestMethod.GET)
	public ModelAndView addSpotCharaGetRequest(@PathVariable("spotId") Long spotId) {
		ModelAndView mav = new ModelAndView(ViewPaths.SPOTCHARA_ADD);
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			mav.setViewName(ViewPaths.USER_LOGIN);
			return mav;
		}
		Integer authority = Authority.PUBLIC;
		Page page = new Page();
		page.setSize(6);
		Spot spot = spotService.view(spotId);
		if (user.getId().equals(spot.getAdministratorId())) {
			authority = Authority.ADMIN;
		}
		List<SpotCharacteristic> scList = spotCharaService.queryCharacteristicBySpotId(spotId,
				page, Activity.NORMAL);
		mav.addObject("spotInfo", spot);
		mav.addObject("scList", scList);
		mav.addObject("authority", authority);
		return mav;

	}

	@RequestMapping(value = "/add", method = RequestMethod.POST)
	public ModelAndView addSpotCharaPostRequest(SpotCharacteristic sc) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		ModelAndView mav = new ModelAndView();
		if (user == null) {
			mav.setViewName(ViewPaths.USER_LOGIN);
			return mav;
		}
		sc.setCreatorId(user.getId());
		sc.setCreatorNickname(user.getNickname());
		sc.setCreatorPortrait(user.getPortrait());
		sc = spotCharaService.addCharacteristic(sc);
		if (sc == null) {
			// TODO 错误页面
			return mav;
		}

		mav.setViewName("redirect:" + sc.getSpotId() + "/" + sc.getId() + "/upload/"
				+ sc.getAlbumId() + ".html");
		return mav;

	}

	/**
	 * 打开批量上传图片到相册的页面
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@RequestMapping(value = "/{spotId}/{spotcharaId}/upload/{albumId}", method = RequestMethod.GET)
	public ModelAndView btachUpload(@PathVariable("spotId") Long spotId,
			@PathVariable("spotcharaId") Long spotcharaId, @PathVariable("albumId") Long albumId) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("上传照片必须登录");
		}
		Album album = albumService.getAlbumForChange(albumId, spotId);
		ModelAndView mav = new ModelAndView(ViewPaths.SPOTCHARA_UPLOADPHOTO);
		mav.addObject("charaId", spotcharaId);
		mav.addObject("spotId", spotId);
		mav.addObject("album", album);
		// WebHelper.saveToken(request);
		return mav;
	}

	private List<ImageResizeResult> processResizeResult(List<ImageResizeResult> results,
			StringBuilder message) {
		List<ImageResizeResult> filesInfo = new ArrayList<ImageResizeResult>();
		for (int i = 0; i < results.size(); i++) {
			ImageResizeResult result = results.get(i);
			ResultState state = result.getResultState();
			switch (state) {
			case SUCCESS:
				filesInfo.add(result);
				break;
			case NOT_IMAGE:
				message.append("上传图片" + result.getOriginalFilename() + "失败，失败原因：图片格式不支持。<br/>");
				break;
			default:
				message.append("上传图片" + result.getOriginalFilename() + "失败。<br/>");
				break;
			}
		}
		return filesInfo;
	}

	@SuppressWarnings("rawtypes")
	private List<SkylineImageResizeTask> prepareResizeTask(List files, long userId, long albumId,
			StringBuilder message) {
		if (files == null || files.isEmpty()) {
			return null;
		}
		boolean isLocal = !(files.get(0) instanceof MultipartFile);
		List<SkylineImageResizeTask> tasks = new ArrayList<SkylineImageResizeTask>(files.size());
		for (Object file : files) {
			long fileSize = 0L;
			String filename = null;
			SkylineImageResizeTask task;
			if (isLocal) {
				File localFile = (File) file;
				fileSize = localFile.length();
				filename = FilenameUtils.getName(localFile.getAbsolutePath());
			} else {
				MultipartFile multipartFile = (MultipartFile) file;
				fileSize = multipartFile.getSize();
				filename = multipartFile.getOriginalFilename();
			}
			if (fileSize == 0) {
				continue;
			}
			if (fileSize > maxSizePerFile) {
				message.append("上传图片" + filename + "失败，失败原因：图片太大。\n");
				continue;
			}
			if (isLocal) {
				File localFile = (File) file;
				task = new LocalImageResizeTask(localFile.getAbsolutePath(), baseSizes);
			} else {
				MultipartFile multipartFile = (MultipartFile) file;
				task = new MultipartImageResizeTask(multipartFile, baseSizes, null, false);
			}
			task.setUserId(userId);
			task.setAlbumId(albumId);
			tasks.add(task);
		}

		return tasks;
	}

	/**
	 * 批量上传压缩文件 用于spot的特色图片上传
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/buploadok/{ownerId}/{albumId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> batchUploadSpotOk(@PathVariable("ownerId") Long ownerId,
			@PathVariable("albumId") Long albumId, @RequestParam("files") String files) {
		Map<String, Object> result = new HashMap<String, Object>();
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		Spot spot = spotService.getSpot(ownerId);
		if (spot == null) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "不存在制定spot");
			return result;
		}
		if (user == null) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "压缩图片必须");
			result.put("logined", Boolean.FALSE);
			return result;
		} else {
			result.put("logined", Boolean.TRUE);
		}
		String[] filesPath = files.split("\\|");
		List<File> localFiles = new ArrayList<File>();
		for (String filePath : filesPath) {
			if (!StringUtils.hasLength(filePath)) {
				continue;
			}
			File localFile = new File(filePath);
			localFiles.add(localFile);
		}
		if (localFiles.isEmpty()) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "没有找到需要压缩的文件！");
			return result;
		}
		StringBuilder message = new StringBuilder();
		List<SkylineImageResizeTask> tasks = prepareResizeTask(localFiles, ownerId, albumId,
				message);
		if (tasks == null || tasks.isEmpty()) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "没有找到需要压缩的文件！");
			return result;
		}

		List<ImageResizeResult> results = imagine.processImage(localStorePath, tasks);
		List<ImageResizeResult> filesInfo = processResizeResult(results, message);

		Album album = null;
		try {
			album = albumService.getAlbumForChange(albumId, ownerId);
		} catch (Exception e) {
			LOGGER.warn("获取相册失败", e);
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "没有找到对应相册，压缩图片失败！");
			return result;

		}
		List<Photo> photos = null;

		if (!filesInfo.isEmpty()) {
			/**
			 * 构造一个spot User
			 */
			User tempUser = new User();
			tempUser.setId(ownerId);
			tempUser.setNickname(spot.getName());
			tempUser.setPortrait(spot.getPortrait());
			photos = albumService.createPhotos(tempUser, album, filesInfo);
		}

		Map<Long, List<Photo>> filesMap = (Map<Long, List<Photo>>) WebHelper.getSessionAttribute(
				null, Constant.SESSION_UPLOAD_OK_FILES);
		if (filesMap == null) {
			filesMap = new HashMap<Long, List<Photo>>();
		}
		filesMap.put(album.getId(), photos);
		WebHelper.setSessionAttribute(null, Constant.SESSION_UPLOAD_OK_FILES, filesMap);

		if (StringUtils.hasLength(message)) {// 存在错误
			result.put("success", Boolean.FALSE);
			result.put("errmsg", message);
		} else {
			result.put("success", Boolean.TRUE);
			result.put("errmsg", "压缩图片成功！");
		}
		return result;
	}

	/**
	 * 修改图片信息
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@RequestMapping(value = "/uploadok/{ownerId}/{charaId}/{albumId}", method = RequestMethod.GET)
	public ModelAndView uploadSpotCharaOk(@PathVariable("ownerId") Long ownerId,
			@PathVariable("charaId") Long charaId, @PathVariable("albumId") Long albumId) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("上传照片必须登录");
		}
//		long userId = user.getId();
		Album album = albumService.getAlbumForChange(albumId, ownerId);
		ModelAndView mav = new ModelAndView(ViewPaths.SPOTCHARA_UPLOADOK);
		mav.addObject("album", album);
		mav.addObject("spotId", ownerId);
		mav.addObject("charaId", charaId);
		// WebHelper.saveToken(request);
		return mav;
	}

	/**
	 * 用于spotChara的图片递交
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@RequestMapping(value = "/uploadok/{ownerId}/{charaId}/{albumId}", method = RequestMethod.POST)
	public ModelAndView uploadSpotCharaOk(@PathVariable("ownerId") Long ownerId,
			@PathVariable("charaId") Long charaId, @PathVariable("albumId") Long albumId,
			String cover, String ext, @RequestParam("description") List<String> descriptions,
			@RequestParam("id") List<Long> ids, String submitToken) {
		User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("上传照片必须登录");
		}
		// if (!WebHelper.isTokenValid(request, true)) {
		// String url = buildRecirectPath(request, URL_PREFIX + "/uploadok/" +
		// albumId);
		// ModelAndView mav = new ModelAndView(new RedirectView(url));
		// return mav;
		// }
		ModelAndView returnMav = null;
		String errMsg = validateForm("uploadOkForm", submitToken);
		if (errMsg != null) {
			returnMav = uploadSpotCharaOk(ownerId, charaId, albumId);
			return processValidationErrors("errMsg", errMsg, returnMav);
		}

		int size = Math.min(ids.size(), descriptions.size());
		StringBuilder errMsgBuilder = new StringBuilder();
		for (int i = 0; i < size; i++) {
			if (ids.get(i) == null) {
				LOGGER.warn("操作失败，ID为:" + albumId + "的相册提交的第" + i + "张图片的ID为空");
			}
			errMsg = validateForm("descriptionOnlyForm", descriptions.get(i));
			if (errMsg != null) {
				if (returnMav == null) {
					returnMav = uploadSpotCharaOk(ownerId, charaId, albumId);
				}
				errMsgBuilder.append("第").append(i + 1).append("张图片的").append(errMsg);
				return processValidationErrors("errMsg", errMsgBuilder.toString(), returnMav);
			}
		}
		albumService.changePhotosDescription(albumId, ids, descriptions);
		albumService.changeAlbumCover(ownerId, albumId, cover, ext);
		spotCharaService.updateCharacteristic(charaId, cover + "." + ext);
		WebHelper.removeSessionAttribute(null, Constant.SESSION_UPLOAD_OK_FILES);
		String url = buildRecirectPath("/spot/chara/detail/" + charaId);
		ModelAndView mav = new ModelAndView(new RedirectView(url));
		return mav;
	}

	@RequestMapping(value = "/detail/{charaId}", method = RequestMethod.GET)
	public ModelAndView showCharaDetail(@PathVariable("charaId") Long charaId) {
		ModelAndView mav = new ModelAndView();
		SpotCharacteristic spotChara = spotCharaService.queryCharacteristicById(charaId,
				Activity.NORMAL);
		if (spotChara == null) {
			mav.setViewName(ViewPaths.SPOT_NOTFOUND);
			return mav;
		}
		mav.addObject("scInfo", spotChara);
		mav.setViewName(ViewPaths.SPOTCHARA_DETAIL);
		return mav;
	}

	/**
	 * 用于删除spot，chara的photo
	 * 
	 * @param ownerId
	 * @param photoId
	 * @return
	 */
	@RequestMapping(value = "/delphoto/{ownerId}/{photoId}", method = { RequestMethod.POST,
			RequestMethod.GET })
	public ModelAndView deleteSpotPhoto(@PathVariable("ownerId") long ownerId,
			@PathVariable("photoId") long photoId) {

		Long albumId = albumService.deletePhoto(ownerId, photoId);
		String url = buildRecirectPath(ALBUM_URL_PREFIX + "/view/" + albumId);
		ModelAndView mav = new ModelAndView(new RedirectView(url));
		return mav;
	}

	@RequestMapping(value = "/vote", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> supportCharRequest(@RequestParam("objId") Long objId,
			@RequestParam("star") Integer star) {
		Map<String, Object> map = new HashMap<String, Object>();
		try {

			User user = (User) WebHelper.getSessionAttribute(null, Constant.SESSION_USER);
			if (user == null) {
				map.put("loginStatus", false);
				return map;
			}
			map.put("loginStatus", true);
			SpotCharacteristic sc = spotCharaService.votes(objId, star);
			map.put("Star", sc.getStar());
			map.put("VoteNum", sc.getVotes());
			return map;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
